package utils.queue
{
import flash.errors.IllegalOperationError;
import flash.events.Event;
import flash.events.EventDispatcher;

import utils.VectorUtil;

[Event(name="complete", type="flash.events.Event")]
[Event(name="cancel", type="flash.events.Event")]
/**
 * QueueList
 * @author jliang
 * 
 */
public class QueueList extends EventDispatcher
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function QueenList()
	{
		super();
	}
	//==========================================================================
	//  Properties
	//==========================================================================
	private var _list:Vector.<Queue> = new Vector.<Queue>();

	public function get list():Vector.<Queue>
	{
		return _list;
	}
	
	private var _isWorking:Boolean = false;

	public function get isWorking():Boolean
	{
		return _isWorking;
	}
	
	private var _currentQueue:Queue;

	public function get currentQueue():Queue
	{
		return _currentQueue;
	}
	
	private var _uid:String;

	public function get uid():String
	{
		return _uid;
	}

	public function set uid(value:String):void
	{
		_uid = value;
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	public function addQueue(queue:Queue):void
	{
		addQueueListener(queue);
        queue.index = list.length;
		list.push(queue);
	}
	
	public function removeQueue(queue:Queue):void
	{
		if (!queue) return;
		queue.cancel();
	}
	
	public function start():void
	{
		if (_isWorking)
		{
			throw new IllegalOperationError("Queue is working now. It can not repeat start.");
			return;
		}
		
		if (list.length == 0)
		{
			allQueueComplete();
			this.dispatchEvent(new Event(Event.COMPLETE));
			return;
		}
		
		_isWorking = true;
		_currentQueue = list[0];
		trace("queen start");
		_currentQueue.start();
	}
	
	public function interrupt():void
	{
		if (_currentQueue)
		{
			_currentQueue.interrupt();
		}
	}
	
	public function remuse():void
	{
		if (_currentQueue)
		{
			_currentQueue.resume();
		}
	}
	
	public function cancel():void
	{
		allQueueCancelHandler(null);
		_isWorking = false;
	}
	//==========================================================================
	//  Private methods
	//==========================================================================
	private function addQueueListener(queue:Queue):void
	{
		queue.addEventListener(QueueEvent.RESUME, queueResumeHandler);
		queue.addEventListener(QueueEvent.INTERRUPT, queueInterruptHandler);
		queue.addEventListener(QueueEvent.CANCEL, queueCancelHandler);
		queue.addEventListener(QueueEvent.CANCEL_ALL, allQueueCancelHandler);
		queue.addEventListener(QueueEvent.COMPLETE, queueCompleteHandler);
	}
	
	private function clearQueueListener(queue:Queue):void
	{
		queue.removeEventListener(QueueEvent.RESUME, queueResumeHandler);
		queue.removeEventListener(QueueEvent.INTERRUPT, queueInterruptHandler);
		queue.removeEventListener(QueueEvent.CANCEL, queueCancelHandler);
		queue.removeEventListener(QueueEvent.CANCEL_ALL, allQueueCancelHandler);
		queue.removeEventListener(QueueEvent.COMPLETE, queueCompleteHandler);
	}
	
	private function allQueueComplete():void
	{
		_list = new Vector.<Queue>();
		_isWorking = false;
		this.dispatchEvent(new Event(Event.COMPLETE));
	}
	//==========================================================================
	//  Event handlers
	//==========================================================================
	private function queueResumeHandler(event:Event):void
	{
		trace("Queue resume");
	}
	
	private function queueInterruptHandler(event:Event):void
	{
		trace("Queue interrupt");
	}
	
	private function queueCancelHandler(event:Event):void
	{		
		trace("Queue cancel");
		var queue:Queue = event.target as Queue;
		VectorUtil.removeObject(queue, list);
		clearQueueListener(queue);
		queue.dipose();
	}
	
	private function allQueueCancelHandler(event:Event):void
	{
		trace("All queue cancel");
		for each (var queue:Queue in list)
		{
			clearQueueListener(queue);
			if (!queue.isCompleted)
			{
				queue.cancelHandler();
			}
			queue.dipose();
		}
		_list = new Vector.<Queue>();
		this.dispatchEvent(new Event(Event.CANCEL));
	}
	
	private function queueCompleteHandler(event:Event):void
	{
		trace("Queue complete");
		var index:int = list.indexOf(event.target as Queue);
		clearQueueListener(event.target as Queue);
		Queue(event.target).dipose();
		
		index ++;
		//all queens completed
		if (index >= list.length)
		{
			allQueueComplete();
		}
		//start next queen
		else
		{
			_currentQueue = list[index];
			trace("Queue start");
			_currentQueue.start();
		}
	}
}
}



